#ifndef __MIRO_H__
#define __MIRO_H__

#include <math.h>
#include <stdlib.h>
#include "OpenGL.h"
#include <stdio.h>
#include <iostream>

//using namespace std;



////////////// platform dependent stuffs

#ifdef WIN32
// use std min and max
#else
#include <stdexcept>
// make our own min and max
//template<class T> inline T max(T a, T b) { return a > b ? a : b; };
//template<class T> inline T min(T a, T b) { return a < b ? a : b; };
//template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; };
#endif




// general constants
const float MIRO_TMAX = 1e12f;
const float epsilon   = 1e-3f;
const float alot	  = 1e15f;
const float PI = 3.1415926535897932384626433832795028841972f;
const float DegToRad = PI/180.0f;
const float RadToDeg = 180.0f/PI;
const float INF = (float)HUGE_VAL;
const float INF4[4] = {INF, INF, INF, INF};
const float N_INF4[4] = {-INF, -INF, -INF, -INF};

const int SHINYMAT = 1;
const int LIGHTMAT = 2;

enum {XAXIS, YAXIS, ZAXIS};
enum {RAYTRACE, PATHTRACE, METROPOLIS, APPM_MEAS, APPM_PHOTON};

//////////////// Settings

// general flags
//#define BETTER_RANDOM
#define SSE			// use SSE optimizations (sqrt, bounding box intersections)
//#define PARALLEL	// use all of the cores!
//#define RAY_STATS	// record ray intersection statistics (does noticeably affect performance)

// ray settings
const char MAX_REFLECTIONS = 8;		// specular reflections, transmission, and path tracing
const int NUM_ANTIALIAS_RAYS = 1;	// AA samples per pixel
const int NUM_LIGHT_SAMPLES	= 0;	// samples per area light
const int NUM_PATHS = 1000;			// for path tracing
const int INIT_PPM_RADIUS = 0.1;	// for PPM
const int NUM_PHOTONS = 100000000;
const float ALPHA = 0.7;

// BVH settings
const int BVH_MAX_NUM_OBJ = 4;		// max number of objects per leaf node
const int BVH_MAX_DEPTH	= 0;//40;		// max depth of BVH (supercedes max number of objects)

#define IOR_AIR	1.0003

class Ray;
class HitInfo;
class Rand;

class Object;
class Sphere;
class Triangle;
class TriangleMesh;
class Instance;

class PointLight;

class Camera;
class Image;
class HdrImage;
class Scene;
class Material;
class Stats;
struct HPoint;
struct AABB;
class List;


extern void ParseFile(FILE* fp);
extern void initOpenGL();
extern Camera * g_camera;
extern Scene * g_scene;
extern Image * g_image;
extern HdrImage * g_hdrImage;
extern Stats g_stats;


// from Toshiya's PPM code
extern unsigned int g_num_hash, g_pixel_index, g_num_photon;
extern double g_hash_s;
extern List **g_hash_grid;
extern List *g_hitpoints;
extern AABB g_hpbbox;


#endif
